package com.whty.common;

import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;



/**
 * XML常量对象，作用类似于数据字典
 * @author leijun
 * @createTime 2010.03.11 pm
 * */
public class XMLConstants {

	private XMLConstants(){
	}
	private static XMLConstants instance = null;
	public synchronized static XMLConstants getInstance(){
		if(instance == null){
			instance = new XMLConstants();
			filePath = Path.getInstance().getWEBINF().replace("/", File.separator) + File.separator + folderName + File.separator + fileName;
			initOrRefreshCache();
		}
		return instance;
	}
	
	
	/* *************************************************************************************
	 * 
	 * */
	private static final String folderName = "xmlconf";
	private static final String fileName = "constants.xml";
	private static final String ACTION_NORMAL = "normal";
	private static Hashtable<String, XMLAction> constTab = null;
	private static String filePath = "";
	
	
	
	/**
	 * 根据KEY值从非特定类别属性中获取设定值（从缓存中获取）
	 * @param key. 关键字
	 * @return 设定值
	 * */
	public String getCacheValue(String key){
		return getCacheValue(key, ACTION_NORMAL);
	}
	
	
	
	/**
	 * 根据KEY值从指定的ACTION类别中获取设定值（从缓存中获取）
	 * @param key. 关键字
	 * @param action. 特定类别标识
	 * @return 设定值
	 * */
	public String getCacheValue(String key, String action){
		String value = "";
		List<XMLProperty> pList = constTab.get(action).getProperties();
		
		XMLProperty item = null;
		Iterator<XMLProperty> itor = pList.iterator();
		while(itor.hasNext()){
			item = itor.next();
			
			if(key.equals(item.getKey())){
				value = item.getValue();
				break;
			}
		}
		return value;
	}
	
	
	
	
	/**
	 * 根据KEY值从非特定类别属性中获取设定值（实时解析XML文件获取最新的设定值）
	 * @param key. 关键字
	 * @return 设定值
	 * */
	public static String getRealtimeValue(String key){
		return getRealtimeValue(key, ACTION_NORMAL);
	}
	
	
	
	
	/**
	 * 根据KEY值从指定的ACTION类别中获取设定值（实时解析XML文件获取最新的设定值）
	 * @param key. 关键字
	 * @param action. 特定类别标识
	 * @return 设定值
	 * */
	public static String getRealtimeValue(String key, String action){
		return parseXMLForValue(key, action);
	}
	
	
	
	
	/**
	 * 根据指定数据类别获得该类别下的设定值键值对
	 * @param action. 指定数据类别
	 * @return Map 指定数据类别下设定的键值对
	 * */
	public Map<String, String> getPropertyMap(String action){
		Map<String, String> pMap = new LinkedHashMap<String, String>();
		List<XMLProperty> pList = constTab.get(action).getProperties();
		
		XMLProperty p = null;
		Iterator<XMLProperty> itor = pList.iterator();
		while(itor.hasNext()){
			p = itor.next();
			
			pMap.put(p.getKey(), p.getValue());
		}
		return pMap;
	}
	
	
	
	
	/**
	 * 根据指定数据类别获得该类别下的设定值对象集合（比键值对拥有更多属性）
	 * @param action. 指定数据类别
	 * @return Map 指定数据类别下设定的键值对
	 * */
	public List<XMLProperty> getProperties(String action){
		XMLAction actionObj = constTab.get(action);
		return actionObj==null ? null : actionObj.getProperties();
	}
	
	
	
	
	/**
	 * 根据指定数据类别和id获得该id下的设定值对象
	 * @param action. 指定数据类别
	 * @param action. 指定数据id
	 * @return XMLProperty 指定数据类别下的键值对象
	 * */
	public XMLProperty getPropertiesById(String action, String id){
		XMLAction actionObj = constTab.get(action);
		List<XMLProperty> param = actionObj.getProperties();
		XMLProperty pro = null;
		for (int i = 0; i < param.size(); i++) {
			pro = param.get(i);
			if (id.equals(pro.getId())) {
				return pro;
			}
		}
		return null;
	}
	

	/**
	 * 初始化XML常量对象，解析XML文件缓存属性值
	 * */
	public static void initOrRefreshCache(){
		if(constTab == null){
			constTab = new Hashtable<String, XMLAction>();
		}else{
			constTab.clear();
		}
		
		try{
			SAXReader reader = new SAXReader();
			Document doc = reader.read(filePath);
			Element root = doc.getRootElement();
			
			Element node = null,
					nNode = null;
			XMLProperty p = null;
			XMLAction action = null;
			List<XMLProperty> pList = null;
			Iterator<?> nItor = null;
			
			Iterator<?> itor = root.elementIterator();
			while(itor.hasNext()){
				node = (Element)itor.next();
				
				try{
					action = new XMLAction();
					action.setId(node.attributeValue("id"));
					action.setDescription(node.attributeValue("description"));
					
					pList = new ArrayList<XMLProperty>();
					nItor = node.elementIterator();
					while(nItor.hasNext()){
						nNode = (Element)nItor.next();
						
						p = new XMLProperty();
						p.setActionId(action.getId());
						
						p.setKey(nNode.attributeValue("key"));
						p.setValue(nNode.attributeValue("value"));
						p.setDescription(nNode.attributeValue("description"));
						// 业务控制追加
						p.setId(nNode.attributeValue("id"));
						p.setName(nNode.attributeValue("name"));
						p.setType(nNode.attributeValue("type"));
						p.setState(nNode.attributeValue("state"));
						p.setTemp(nNode.attributeValue("temp"));
						p.setAction(nNode.attributeValue("action"));
						p.setCache(nNode.attributeValue("cache"));
						p.setView(nNode.attributeValue("view"));
						p.setCondition(nNode.attributeValue("condition"));
						p.setIsPage(nNode.attributeValue("isPage"));
						p.setStartNum(nNode.attributeValue("startNum"));
						p.setCountNum(nNode.attributeValue("countNum"));
						p.setSingleAction(nNode.attributeValue("singleaction"));
						p.setSingleType(nNode.attributeValue("singletype"));
						pList.add(p);
					}
					action.setProperties(pList);
					
					constTab.put(action.getId(), action);
				}catch(Exception we){
					continue;
				}								
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	
	
	
	/**
	 * 解析XML文件获取指定设定值
	 * @param key. 关键字
	 * @param action. 特定类别标识
	 * @return 设定值
	 * */
	private static String parseXMLForValue(String key, String action){
		String value = "";
		boolean found = false;
		try{
			String path = Path.getInstance().getWEBINF().replace("/", File.separator) + File.separator + folderName + File.separator + fileName;
			
			SAXReader reader = new SAXReader();
			Document doc = reader.read(path);
			Element root = doc.getRootElement();
			
			Element node = null,
					nNode = null;
			Iterator<?> nItor = null;
			
			Iterator<?> itor = root.elementIterator();
			while(itor.hasNext()){
				if(found){
					break;
				}
				node = (Element)itor.next();
				
				try{
					if(action.equals(node.attributeValue("id"))){
						nItor = node.elementIterator();
						
						while(nItor.hasNext()){
							nNode = (Element)nItor.next();
							
							if(key.equals(nNode.attributeValue("key"))){
								value = nNode.attributeValue("value");
								found = true;
								break;
							}
						}
					}
				}catch(Exception ex){
					continue;
				}
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return value;
	}
}
